<!--
 * @Author: Dorange.Wang
 * @Date: 2021-06-09 16:46:05
 * @LastEditors: your name
 * @LastEditTime: 2021-09-28 14:55:12
 * @Description: file content
-->
<template>
  <div class="container">
    <div class="header" v-if="!disabled">
      <div class="left">
        <el-select
          class="field-selector"
          v-model="currentField"
          placeholder="请选择显示字段"
          @change="handleFieldChange"
          clearable
        >
          <el-option
            v-for="field in validFields"
            :key="field.value"
            :value="field.value"
            :label="`${field.label}[${field.value}]`"
          >
          </el-option>
        </el-select>

        <div class="default-symbols">
          <el-button v-for="symbol in symbols" :key="symbol" @click="handleSymbolClick(symbol)">
            {{ symbol }}
          </el-button>
        </div>

        <el-input
          v-model="customSymbol"
          class="custom-symbol"
          placeholder="自定义分隔符"
          :maxlength="64"
          @keyup.enter.native="handleCustomSymbolOk"
        >
          <el-button slot="append" icon="el-icon-check" @click="handleCustomSymbolOk"></el-button>
        </el-input>
      </div>

      <div v-if="clearable" class="right">
        <el-button type="text" @click="handleEmpty">
          <i class="el-icon-delete"/>
          <span>清空</span>
        </el-button>
      </div>

    </div>

    <div class="content">
      <!-- <el-tag
        v-for="(ele,index) in valueList"
        :key="index"
        closable
        type="info"
        @close="handleDelete(index)"
      >
        {{ ele.label }}
      </el-tag> -->

      <div
        class="value-item"
        v-for="(ele,index) in valueList"
        :key="index"
      >
        {{ ele.label }}
        <i v-if="!disabled" class="delete-icon el-icon-circle-close del" @click="handleDelete(index)"/>
      </div>
    </div>
    <div v-if="resultVisible" class="footer">
      {{ expression }}
    </div>
  </div>
</template>

<script>
const FIELD_REG = /\${\w+}/g
export default {
  name: 'LabelExpression',

  model: {
    prop: 'value',
    event: 'change'
  },

  props: {
    fields: { // 字段列表
      type: Array,
      default: () => []
    },
    value: { // 表达式
      type: String,
      default: ''
    },
    symbols: { // 组件使用的符号，特殊场景自行覆盖
      type: Array,
      default: () => ['+', '-', '/', '_', '[', ']']
    },
    resultVisible: { // 展示输出结果
      type: Boolean,
      default: false
    },
    disabled: { // 禁用 todo
      type: Boolean,
      default: false
    },
    clearable: { // 清空按钮
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      currentField: undefined, // 当前选中的字段
      valueList: [], // 选中的集合
      valueIndex: 0, // 选中值的索引 用于在表达式中间插入值
      customSymbol: '' // 自定义符号
    }
  },
  computed: {
    validFields () {
      return this.fields.map(item => {
        return {
          ...item,
          __value__: '${' + item.value + '}'
        }
      })
    },
    expression () {
      return this.valueList.map(item => item.value).join('')
    }
  },

  watch: {
    fields: {
      handler: 'initExpression',
      immediate: true
    },
    value: {
      handler: 'initExpression',
      immediate: true
    }
  },

  methods: {
    /**
     * 根据字段列表和表达式的解析出选中列表
     */
    initExpression () {
      // if (!this.fields || this.fields.length === 0 || !this.value) {
      //   this.valueList = []
      //   return false
      // }
      if (!this.value) {
        this.valueList = []
        return false
      }

      const valueList = []
      const fields = this.value.match(FIELD_REG) || []
      const symbols = this.value.split(FIELD_REG) || []

      // if (!fields) {
      //   this.valueList = []
      //   return false
      // }

      for (let i = 0; i < symbols.length; i++) {
        if (symbols[i]) {
          valueList.push({
            value: symbols[i],
            label: symbols[i],
            __type__: 'SYMBOL'
          })
        }

        // 字段永远比分隔符少一个
        if (fields[i]) {
          const field = this.validFields.find(item => item.__value__ === fields[i])
          if (field) {
            valueList.push({
              value: field.__value__,
              label: field.label,
              __type__: 'FIELD'
            })
          } else {
            valueList.push({
              value: fields[i],
              label: fields[i],
              __type__: 'SYMBOL'
            })
          }
        }
      }
      this.valueList = valueList
    },

    handleFieldChange (value) {
      if (!value) {
        return
      }
      const field = this.validFields.find(i => i.value === value)
      this.valueList.push({
        value: field.__value__,
        label: field.label,
        __type__: 'FIELD'
      })

      this.currentField = ''
      this.$emit('change', this.expression)
    },

    handleSymbolClick (value) {
      this.valueList.push({
        value,
        label: value,
        __type__: 'SYMBOL'
      })
      this.$emit('change', this.expression)
    },

    handleCustomSymbolOk () {
      const symbol = this.customSymbol || ''
      this.valueList.push({
        value: symbol,
        label: symbol,
        __type__: 'SYMBOL'
      })
      this.customSymbol = ''
      this.$emit('change', this.expression)
    },

    handleDelete (index) {
      this.valueList.splice(index, 1)
      this.$emit('change', this.expression)
    },

    handleEmpty () {
      this.valueList = []
      this.$emit('change', this.expression)
    }
  }
}
</script>

<style lang="scss" scoped>
.container{
  border: 1px solid #ddd;
  border-radius: 3px;
  box-sizing: border-box;

  .header{
    padding: 10px 10px 0 10px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    border-bottom: 1px solid #ddd;

    .left{
      width: 80%;
      display: flex;
      flex-wrap: wrap;
      .field-selector{
        width: 240px;
        margin-right: 20px;
        margin-bottom: 10px;
      }
      .default-symbols{
        margin-right: 20px;
        margin-bottom: 10px;
      }
      .custom-symbol{
        width: 240px;
        margin-bottom: 10px;
      }
    }
  }

  .content{
    $tagSize: 30px;
    $space: 10px;
    min-height: $tagSize + $space;
    padding: 10px 10px 0 10px;
    display: flex;
    flex-wrap: wrap;

    .value-item{
      display: inline-block;
      height: $tagSize - 2px;
      padding: 0 15px;
      border: 1px solid #ddd;
      line-height: $tagSize - 2px;
      border-radius: 3px;
      font-weight: bold;
      margin-right: $space;
      margin-bottom: $space;
      cursor: pointer;
      position: relative;

      .delete-icon{
        position: absolute;
        top: -6px;
        right: -6px;
        font-size: 16px;
        background: #fff;
        display: none;
      }

      &:hover .delete-icon{
        display: block;
      }
    }
  }

  .footer{
    border-top: 1px solid #ddd;
    display: flex;
    align-items: center;
    padding: 5px 10px;
  }

  .divider{
    margin: 0 20px;
  }
}
</style>
